<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>Pelican语法高亮</title>

    <link rel="stylesheet" href="../../theme/css/style.css">
    <link rel="stylesheet" href="../../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>Pelican语法高亮</h1>    <p>
        under
            <a href="../../tags/blog/">blog</a>
            <a href="../../tags/pelican/">pelican</a>
            <a href="../../tags/restructuredtext/">restructuredtext</a>
            <a href="../../tags/sphinx/">sphinx</a>
            <a href="../../tags/docutils/">docutils</a>
            <a href="../../tags/pygments/">pygments</a>
    </p>
    <p>
        in <a href="../../categories/tech/">tech</a>
    </p>
    <p>Published: 2016-09-17</p>


    <p>以前我一直使用<tt class="docutils literal">code</tt>指令标记代码，生成的HTML文档里也确实为不同的语言元素加了不同的类属性，认为只要随便加一个css就可以实现语法高亮功能，最近试了<a class="reference external" href="https://github.com/PurePelicanTheme/pure/blob/9c58a20c1ed86a26c456ac1f3a736838b6409fc1/static/css/pygments.css">pure</a>和<a class="reference external" href="https://github.com/getpelican/pelican-themes/tree/master/pelican-bootstrap3/static/css/pygments">pelican-bootstrap3</a>的pygments.css都不行，很纳闷。但仔细看一下就明白了，这两个css文件都要求代码有一个类属性为<tt class="docutils literal">highlight</tt>的父HTML元素，但实际生成的HTML文档里，代码是<tt class="docutils literal">&lt;pre <span class="pre">class=&quot;code</span> python <span class="pre">literal-block&quot;&gt;</span></tt>元素，整篇文档中都没有类属性为<tt class="docutils literal">highlight</tt>的元素，也难怪语法高亮没有起作用。</p>
<p>搜索后发现使用这些主题的站点一般用<tt class="docutils literal"><span class="pre">code-block</span></tt>指令来标记代码，试验后发现它果然在代码的<tt class="docutils literal">&lt;pre&gt;</tt>元素外面套了个<tt class="docutils literal">&lt;div <span class="pre">class=&quot;highlight&quot;&gt;</span></tt>元素，于是这两种CSS文件都可以高亮显示文章里面的代码。在<a class="reference external" href="http://docutils.sourceforge.net/">docutils的文档</a>里，通篇只有<a class="reference external" href="http://docutils.sourceforge.net/docs/user/links.html">一个地方</a>提到这个指令：</p>
<blockquote>
rstcheck Checks syntax of reStructuredText and code blocks nested within it.
(Using the Sphinx syntax &quot;code-block&quot; for the &quot;code&quot; directive.)</blockquote>
<p>可见这个指令不是docutils自带的，可能是<a class="reference external" href="http://www.sphinx-doc.org/en/stable/">Sphinx</a>引入的，在其代码sphinx/directives/code.py里可以看到：</p>
<div class="highlight"><pre><span></span><span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s1">&#39;code-block&#39;</span><span class="p">,</span> <span class="n">CodeBlock</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s1">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">CodeBlock</span><span class="p">)</span>
</pre></div>
<p>确实是注册了<tt class="docutils literal"><span class="pre">code-block</span></tt>和<tt class="docutils literal">sourcecode</tt>两个指令，并都和<tt class="docutils literal">CodeBlock</tt>类关联。</p>
<p><a class="reference external" href="http://docs.getpelican.com/en/stable/">Pelican</a>也有类似的代码在pelican/rstdirectives.py里，指令名完全一样：</p>
<div class="highlight"><pre><span></span><span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s1">&#39;code-block&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s1">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
</pre></div>
<p>在其<a class="reference external" href="http://docs.getpelican.com/en/stable/content.html?highlight=code-block">文档</a>里明确地提到用<tt class="docutils literal"><span class="pre">code-block</span></tt>标记需要被高亮的代码。</p>
<p>docutils里用<tt class="docutils literal">code</tt>指令标记的代码可以被高亮，因为rst2html生成的CSS代码里，语法高亮的类属性前没有<tt class="docutils literal">.highlight</tt>或<tt class="docutils literal">pre</tt>前缀。至于为什么Sphinx和Pelican要“多此一举”，可能是需要为代码标记指令添加功能，两个框架各自设计了若干个指令选项，但共同的只有<tt class="docutils literal">linenos</tt>，docutils代码在docutils/parsers/rst/languages/en.py里添加了一个本地语言映射，将<tt class="docutils literal"><span class="pre">code-block</span></tt>指令作为<tt class="docutils literal">code</tt>指令的别名，提供了一定程度上的兼容，但不支持Sphinx或Pelican同名指令的选项。</p>
<p>以前用<tt class="docutils literal">code</tt>标记代码的文章，如果想用这些带<tt class="docutils literal">.highlight</tt>前缀的CSS文件实现语法高亮，有两种选择：</p>
<ul class="simple">
<li>将<tt class="docutils literal">code</tt>指令替换成<tt class="docutils literal"><span class="pre">code-block</span></tt>指令，但后者不能省略语言参数，建议将不带语言参数的<tt class="docutils literal">code</tt>指令替换为literal block，即两个冒号。</li>
<li>将其嵌入到<tt class="docutils literal">.. container:: highlight</tt>指令中，用<tt class="docutils literal">include</tt>指令嵌入的代码只能这么修改。</li>
</ul>
<p>（完）</p>

    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="../..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../../categories/">categories</a>
        <a href="../..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>